#include <jni.h>
#include <string>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <termios.h>
#include <unistd.h>
#include <fcntl.h>

#include "android/log.h"
static const char *TAG = "serial_port";
#define LOGI(fmt, args...) __android_log_print(ANDROID_LOG_INFO,  TAG, fmt, ##args)
#define LOGD(fmt, args...) __android_log_print(ANDROID_LOG_DEBUG, TAG, fmt, ##args)
#define LOGE(fmt, args...) __android_log_print(ANDROID_LOG_ERROR, TAG, fmt, ##args)


//extern "C"
//JNIEXPORT jstring JNICALL
//Java_com_example_ztlchina_forthapp_MainActivity_stringFromJNI(
//Java_com_EnsentecLib_EnsenLib_stringFronJNI (
//        JNIEnv *env,
//        jobject /* this */) {
//    //std::string hello = "Hello from C++";
//    return env->NewStringUTF(hello.c_str());
//}

extern "C"
JNIEXPORT void JNICALL
Java_com_ensentec_Lib_EnsenLib_motorRun(
        JNIEnv *env,
        jobject /* this */) {
    system("echo 2 > /sys/devices/platform/ensentec_io/state");     //拉低控制引脚， 正转
    usleep(500000);
    system("echo 1 > /sys/devices/platform/ensentec_io/state");     //上电

}

extern "C"
JNIEXPORT void JNICALL
Java_com_ensentec_Lib_EnsenLib_motorRunInvert(
        JNIEnv *env,
        jobject /* this */)
{
    system("echo 3 > /sys/devices/platform/ensentec_io/state");     //拉高控制引脚， 反转
    usleep(500000);
    system("echo 1 > /sys/devices/platform/ensentec_io/state");     //上电
}

extern "C"
JNIEXPORT void JNICALL
Java_com_ensentec_Lib_EnsenLib_motorStop(
        JNIEnv *env,
        jobject /* this */)
{
    system("echo 0 > /sys/devices/platform/ensentec_io/state");     //断电
}


extern "C"
JNIEXPORT void JNICALL      //推拉杆1 推动作
Java_com_ensentec_Lib_EnsenLib_pushRod1Push(
        JNIEnv *env,
        jobject /* this */)
{
    system("echo 4 > /sys/devices/platform/ensentec_io/state");     //上电
}

extern "C"
JNIEXPORT void JNICALL      //推拉杆1 拉动作
Java_com_ensentec_Lib_EnsenLib_pushRod1Pull(
        JNIEnv *env,
        jobject /* this */)
{
    system("echo 5 > /sys/devices/platform/ensentec_io/state");     //上电
}


extern "C"
JNIEXPORT void JNICALL      //推拉杆2 推动作
Java_com_ensentec_Lib_EnsenLib_pushRod2Push(
        JNIEnv *env,
        jobject /* this */)
{
    system("echo 6 > /sys/devices/platform/ensentec_io/state");     //上电
}

extern "C"
JNIEXPORT void JNICALL      //推拉杆2 拉动作
Java_com_ensentec_Lib_EnsenLib_pushRod2Pull(
        JNIEnv *env,
        jobject /* this */)
{
    system("echo 7 > /sys/devices/platform/ensentec_io/state");     //上电
}

extern "C"
JNIEXPORT void JNICALL      //电子锁1开
Java_com_ensentec_Lib_EnsenLib_lock1Open(
        JNIEnv *env,
        jobject /* this */)
{
    system("echo 9 > /sys/devices/platform/ensentec_io/state");     //上电
    usleep(700000);
    system("echo 8 > /sys/devices/platform/ensentec_io/state");     //上电

}


extern "C"
JNIEXPORT void JNICALL      //电子锁2开
Java_com_ensentec_Lib_EnsenLib_lock2Open(
        JNIEnv *env,
        jobject /* this */)
{
    system("echo 11 > /sys/devices/platform/ensentec_io/state");     //上电
    usleep(700000);
    system("echo 10 > /sys/devices/platform/ensentec_io/state");     //上电

}


extern "C"
JNIEXPORT void JNICALL      //电子锁3开
Java_com_ensentec_Lib_EnsenLib_lock3Open(
        JNIEnv *env,
        jobject /* this */)
{
    system("echo 13 > /sys/devices/platform/ensentec_io/state");     //上电
    usleep(700000);
    system("echo 12 > /sys/devices/platform/ensentec_io/state");     //上电

}


extern "C"
JNIEXPORT void JNICALL      //电子锁4开
Java_com_ensentec_Lib_EnsenLib_lock4Open(
        JNIEnv *env,
        jobject /* this */)
{
    system("echo 15 > /sys/devices/platform/ensentec_io/state");     //上电
    usleep(700000);
    system("echo 14 > /sys/devices/platform/ensentec_io/state");     //上电

}


extern "C"
JNIEXPORT void JNICALL      //电子锁5开
Java_com_ensentec_Lib_EnsenLib_lock5Open(
        JNIEnv *env,
        jobject /* this */)
{
    system("echo 17 > /sys/devices/platform/ensentec_io/state");     //上电
    usleep(700000);
    system("echo 16 > /sys/devices/platform/ensentec_io/state");     //上电

}


void RS485Read(void)
{
    system("echo 22 > /sys/devices/platform/ensentec_io/state");     //低点评;
}
void RS485Write(void)
{
    system("echo 23 > /sys/devices/platform/ensentec_io/state");     //低点评;
}

//jint GetIOValue()
//{
//    int size;
//    FILE *fd = NULL;
//    char buffer[16];
//    memset(buffer,0,16);
//
//    fd = fopen("/sys/devices/platform/ensentec_io/state", "r");
//    if(fd == NULL)
//    {
//        return  env->NewStringUTF("");//(*env)->NewStringUTF(env, "444444444");
//    }
//
//    size = fread(buffer, sizeof(char), 15, fd);
//    fclose(fd);
//
//    ;
//}

//extern "C"
//JNIEXPORT void JNICALL      //电子锁5开
//Java_com_ensentec_Lib_IOCtrl_IO485Read(
//        JNIEnv *env,
//        jobject /* this */)
//{
//    system("echo 22 > /sys/devices/platform/ensentec_io/state");     //低点评
//}
//
//extern "C"
//JNIEXPORT void JNICALL      //电子锁5开
//Java_com_ensentec_Lib_IOCtrl_IO485Write(
//        JNIEnv *env,
//        jobject /* this */)
//{
//    system("echo 23 > /sys/devices/platform/ensentec_io/state");     //高点评
//}


extern "C"
JNIEXPORT jstring JNICALL      //电子锁5开
Java_com_ensentec_Lib_EnsenLib_IOStatus(
        JNIEnv *env,
        jobject /* this */)
{
    int size;
    FILE *fd = NULL;
    char buffer[16];
    memset(buffer,0,16);

    fd = fopen("/sys/devices/platform/ensentec_io/state", "r");
    if(fd == NULL)
    {
        return  env->NewStringUTF("");//(*env)->NewStringUTF(env, "444444444");
    }

    size = fread(buffer, sizeof(char), 15, fd);
    fclose(fd);

    return (env)->NewStringUTF(buffer);
}



int openserial(const char *portname)
{
    int serialfd;

//    char				portname[20];
//    portid = comport;

//    sprintf( portname, "/dev/ttyAMA%d", comport );        //z
//    //sprintf( portname, "/dev/ttyUSB%d", comport );

    serialfd = open(portname, O_RDWR | O_NOCTTY | O_NONBLOCK);
    if ( - 1 == serialfd)
    {
        LOGE("Can not open serial %s", portname);
    }

    LOGI("Open serial %s, fd:%d", portname, serialfd);

    return serialfd;
}

/**
 * 设置串口参数
 * @param serialfd 串口描述符
 * @param nBits     数据位
 * @param nSpeed    波特率
 * @param nEvent    校验位 'O' 奇校验   'E' 偶校验  'N'无校验
 * @param nStop     停止位
 * @param block     是否阻塞读取
 * @return
 */
int setSerial(int serialfd, int nSpeed, unsigned char nEvent,  int nBits,  int nStop, int block)
{
    struct termios newtio, oldtio;
    LOGD("setSerial serialfd:%d,nBits:%d, nSpeed:%d, nEvent:%c, nStop:%d, block:%d\n",
           serialfd, nBits, nSpeed, nEvent, nStop, block);

    //m_nBits = nBits; m_nSpeed = nSpeed; m_nStop = nStop;m_nEvent = nEvent;

    /* save olde termios status */
    if (tcgetattr(serialfd, &oldtio) != 0)
    {
        LOGE("Setserial err tcgetattr.\n");
        return  - 1;
    }

    //bzero(&newtio, sizeof(newtio));
    memset(&newtio,  0, sizeof(newtio));
    /* mask the character size bits */
    newtio.c_iflag = 0;
    newtio.c_oflag = 0;
    newtio.c_lflag = 0;

    newtio.c_cflag |= (CLOCAL | CREAD);
    newtio.c_cflag &= ~CSIZE;

    switch (nBits)
    {
        case 7:
            newtio.c_cflag |= CS7;
            break;
        case 8:
            newtio.c_cflag |= CS8;
            break;
        default:
            newtio.c_cflag |= CS8;
            break;
    }

    /* set parity check bit */
    switch (nEvent)
    {
        case 'O':
            newtio.c_cflag |= PARENB;
            newtio.c_cflag |= PARODD;
            //newtio.c_iflag |= (INPCK | ISTRIP); //ISTRIP ���ַ����вü�Ϊ7λ
            newtio.c_iflag = INPCK;
            break;
        case 'E':
            //newtio.c_iflag |= (INPCK | ISTRIP);
            newtio.c_iflag = INPCK;
            newtio.c_cflag |= PARENB;
            newtio.c_cflag &= ~PARODD;
            break;
        case 'N':
            newtio.c_cflag &= ~PARENB;
            break;
        default:
            newtio.c_cflag &= ~PARENB;
            break;
    }

    /* set baud rate */
    switch (nSpeed)
    {
        case 1200:
            cfsetispeed(&newtio, B1200);
            cfsetospeed(&newtio, B1200);
            break;
        case 2400:
            cfsetispeed(&newtio, B2400);
            cfsetospeed(&newtio, B2400);
            break;
        case 4800:
            cfsetispeed(&newtio, B4800);
            cfsetospeed(&newtio, B4800);
            break;
        case 9600:
            cfsetispeed(&newtio, B9600);
            cfsetospeed(&newtio, B9600);
            break;
        case 19200:
            cfsetispeed(&newtio, B19200);
            cfsetospeed(&newtio, B19200);
            break;
        case 38400:
            cfsetispeed(&newtio, B38400);
            cfsetospeed(&newtio, B38400);
            break;
        case 115200:
            cfsetispeed(&newtio, B115200);
            cfsetospeed(&newtio, B115200);
            break;
        case 460800:
            cfsetispeed(&newtio, B460800);
            cfsetospeed(&newtio, B460800);
            break;
        default:
            cfsetispeed(&newtio, B9600);
            cfsetospeed(&newtio, B9600);
            break;
    }

    /* set stop bit */
    switch (nStop)
    {
        case 1:
            newtio.c_cflag &= ~CSTOPB;
            break;
        case 2:
            newtio.c_cflag |= CSTOPB;
            break;
        default:
            newtio.c_cflag |= CSTOPB;
            break;
    }

    /* disable hardware flow control */
    newtio.c_cflag &= ~CRTSCTS;
    /* set rawoutput */
    newtio.c_oflag &= ~OPOST;

    /* raw input */
    newtio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);

    /* set wait time */
    if (block == 0)
    {
        newtio.c_cc[VTIME] = 0; /*set overtime is 200 microsecond*/
        newtio.c_cc[VMIN] = 0;
    }
    else
    if (block == 1)
    {
        newtio.c_cc[VTIME] = 0; /*set overtime is 200 microsecond*/
        newtio.c_cc[VMIN] = 1;
    }

    tcflush(serialfd, TCIFLUSH);

    if ((tcsetattr(serialfd, TCSANOW, &newtio)) != 0)
    {
        LOGE("com set error");
        return  - 1;
    }
    LOGD("Set serial ok.");
    return 0;
}


/**
 * 带时间的读取串口
 * @param serialfd 串口描述符
 * @param buff  读取缓冲区
 * @param maxbufflen 最大读取个数
 * @param waitsec 等待时间 秒
 * @return 读取的个数
 */
int select_read(int serialfd, unsigned char *buff, int maxbufflen, int waitsec)
{
    int num = 0;
    int i = 0;
    int ret = 0;
    int totalread = 0;
    fd_set fdset;
    char tempbuff[128] = {0};
    struct timeval wait_time;

    totalread = 0;
    waitsec = waitsec > 0 ? waitsec:0;

    /* read the return value */
    FD_ZERO(&fdset);
    FD_SET(serialfd, &fdset);
    wait_time.tv_sec = waitsec;
    wait_time.tv_usec = 100000;
    ret = select(serialfd+1, &fdset,  (fd_set *)NULL, (fd_set *)NULL, &wait_time);
    if (ret <= 0)
    {
        return ret;
    }

    do
    {
        num = read(serialfd, tempbuff + totalread, maxbufflen - totalread);
        if (num <= 0) //返回值为0，可能出现。这里必须跳出，否则将造成死循环
            break;
        totalread += num;
        FD_ZERO(&fdset);
        FD_SET(serialfd, &fdset);
        wait_time.tv_sec =  0;
        wait_time.tv_usec = 100000;//(1000000000/COM_BAUT_RATE + 1) = 833000us; //
        ret = select(serialfd+1, &fdset,  (fd_set *)NULL, (fd_set *)NULL, &wait_time);

    }while(ret > 0);

    if (totalread == -1)
    {
        LOGE("read com error");
    }
    else {
        memcpy(buff, tempbuff, totalread);
        buff[totalread] = 0;
    }
    return totalread;;
}



int select_write(int serialfd, unsigned char *buff, int writelen, int waitsec)
{
    int num = 0;
    int i = 0;
    int ret = 0;
    int totalwrite = 0;
    fd_set fdset;
    struct timeval wait_time;

    totalwrite = 0;
    waitsec = waitsec > 0 ? waitsec:0;

    /* read the return value */
    FD_ZERO(&fdset);
    FD_SET(serialfd, &fdset);
    wait_time.tv_sec = waitsec;
    wait_time.tv_usec = 0;
    ret = select(serialfd+1, (fd_set *)NULL, &fdset, (fd_set *)NULL, &wait_time);
    if (ret <= 0)
    {
        LOGE("write timeout");
        return ret;
    }
    do
    {
        num = write(serialfd, buff + totalwrite, writelen - totalwrite);
        totalwrite += num;
        if (num <= 0)
            break;
        else
        if (totalwrite >= writelen)
            break;

        FD_ZERO(&fdset);
        FD_SET(serialfd, &fdset);
        wait_time.tv_sec =  0;
        wait_time.tv_usec = 50000;//(1000000000/COM_BAUT_RATE + 1) = 833000us; //
        ret = select(serialfd+1, (fd_set *)NULL, &fdset, (fd_set *)NULL, &wait_time);
    }while(ret > 0 && ++i < 3); //连续发3次

    return totalwrite;;
}


static unsigned char auchCRCHi[] = {
        0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
        0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
        0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
        0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
        0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
        0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
        0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
        0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
        0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
        0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
        0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
        0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
        0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
        0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
        0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
        0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
        0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
        0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
        0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
        0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
        0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
        0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
        0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
        0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
        0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
        0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
} ;

static char auchCRCLo[] = {
        0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06,
        0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD,
        0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,
        0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A,
        0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4,
        0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
        0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3,
        0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4,
        0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,
        0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29,
        0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED,
        0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
        0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60,
        0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67,
        0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,
        0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68,
        0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E,
        0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
        0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71,
        0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92,
        0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,
        0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B,
        0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B,
        0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
        0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42,
        0x43, 0x83, 0x41, 0x81, 0x80, 0x40
} ;
unsigned short CRC16(unsigned char *puchMsg, unsigned short usDataLen)
{
    unsigned char uchCRCHi = 0xFF ;
    unsigned char uchCRCLo = 0xFF ;
    unsigned uIndex ;
    while (usDataLen--)
    {
        uIndex = uchCRCHi ^ *puchMsg++ ;
        uchCRCHi = uchCRCLo ^ auchCRCHi[uIndex] ;
        uchCRCLo = auchCRCLo[uIndex] ;
    }
    return (uchCRCHi << 8 | uchCRCLo) ;
}
//
//extern "C"
//JNIEXPORT jint JNICALL
//Java_com_ensentec_Lib_EnsenLib_openserial(
//        JNIEnv *env,
//        jobject thiz,
//        jstring path,jint baudrate,jint nBits,
//        jchar nEvent, jint nStop, jint block)
//
//{
//    int fd;
//    int ret;
//    jboolean iscopy;
//    const char *path_utf = env->GetStringUTFChars(path, &iscopy);
//    LOGD("Opening serial port %s and set bardrate:%d", path_utf, baudrate);
//    fd = openserial(path_utf);
//    if (fd > 0)
//    {
//        LOGD(" sucess.\n");
//    }
//    else {
//        LOGD("fail.\n");
//        return -1;
//    }
//
//    ret = setSerial(fd, baudrate, nEvent, nBits, nStop, block);
//    if (ret < 0)
//    {
//        LOGE("set serial(%s) fail.\n", path_utf);
//        return -2;
//    }
//    else
//        return fd;
//}
//
//
//extern "C"
//JNIEXPORT jint JNICALL
//Java_com_ensentec_Lib_EnsenLib_closeserial
//        (   JNIEnv *env,
//            jobject thiz,
//            jint fd)
//{
//    if (fd > 0)
//    {
//        close(fd);
//        fd = -1;
//    }
//    return fd;
//}

#define  DEV_PATH_ElecScale   "/dev/ttySAC2"
#define  DEV_BARD_ElecScale    9600
#define  DEV_NBIT_ElecScale    8
#define  DEV_NSTOP_ElecScale   1
#define  DEV_NEven_ElecScale   'N'

extern "C"
JNIEXPORT jint JNICALL
/**
 * 读取电子秤重量
 * @param env
 * @param thiz
 * @param times
 * @return -1: Open serial error.
 *         -2: Set serial error;
 *         -3: Write serial error;
 *         -4: Read serial error;
 *         -10 : 参数错误;
 *
 */
Java_com_ensentec_Lib_EnsenLib_ElecScaleReadValue
        (   JNIEnv *env,
            jobject thiz, int times)
{
    int fd = 0;
    int ret = 0;
    int i = 0, k = 0;
    int flag = 0;
    int weight = 0;//单位:克
    unsigned char cmdbuff[8] = {0x1F, 0x03, 0x00, 0x2A, 0x00, 0x01, 0xA6, 0x7C};
    unsigned char readbuff[128] = {0};
    int getvalue[32] = {0};
    int total = 0;
    int value;
    int errtimes = 0;
    int readok = 0;

    times = times > 32 ? 32 : times;

    if (times <= 0)
        return -10;

    fd = openserial(DEV_PATH_ElecScale);
    if (fd < 0)
    {
        LOGE("Open ElecScale serial(%s) error.", DEV_PATH_ElecScale);
        return -1;
    }

    ret = setSerial(fd, DEV_BARD_ElecScale, DEV_NEven_ElecScale, DEV_NBIT_ElecScale, DEV_NSTOP_ElecScale, 1);
    if (ret != 0)
    {
        LOGE("Set ElecScale serial(%s) error.", DEV_PATH_ElecScale);
        close(fd);
        return  -2;
    }


    /*

    R_CWV
    输       入：0x1F 0x03 0x00 0x2A 0x00 0x01 0xA6 0x7C
    功       能：读取数字模块当前测量值，绝对值小于32000的测量值
    回 答 信 息：0x1F 0x03 0x02 0xXX 0xYY 0xCC 0xDD
               xxyy为十六进制称重值
    例：发送：1F 03 00 2A 00 01 A6 7C
       回复：1F 03 02 4E 02 A4 27   称重值4E02即10进制19970

    地址编号为1F模块清零：
    输入：1F 06 00 24 00 00 CA 7F
    回复：1F 06 00 24 00 00 CA 7F

    */


    for (int i = 0; i < times; i++)
    {
        //RS485Write();
        //usleep(10000);          //10ms
        //ret = select_write(fd, cmdbuff, sizeof(cmdbuff), 0);
        ret = write(fd, cmdbuff, sizeof(cmdbuff));
        if (ret != sizeof(cmdbuff))
        {
            continue;
//            LOGE("ElecScale serial write not all data.want(%d),send(%d).\n", sizeof(cmdbuff), ret);
//            close(fd);
//            return -3;
        }

        //RS485Read();
        //usleep(100);          //10ms
        ret = select_read(fd, readbuff, sizeof(readbuff), 1);
        if (ret <=  0)
        {
            continue;
//            LOGE("ElecScale serial read err(%d).\n", ret);
//            close(fd);
//            return -4;
        }

        flag = 0;
        for (k = 0; k <= ret - 7; k++)
        {
            //1F 03 02 4E 02 A4 27
            if (readbuff[k] == 0x1f  && readbuff[k+1] == 0x03
                    && readbuff[k+2] == 0x02) {
                flag = 1;
                break;
            }
        }

        if (flag && (CRC16(readbuff + k, 7) == 0))
        {
            getvalue[readok] = readbuff[k+3] << 8 | readbuff[k+4];
            LOGD("ElecScale get onece value:%d\n", getvalue[times]);
            total += getvalue[readok];
            readok ++;
        }
    }

    if (readok == 0)
    {
        return -3;
    }
    else {
        value = total / readok;
        LOGD("ElecScale get value:%d, sucess times:%d\n", value, readok);
    }

    close(fd);
    return value;
}


extern "C"
JNIEXPORT jint JNICALL
Java_com_ensentec_Lib_EnsenLib_ElecScaleClearWeight
        (   JNIEnv *env,
            jobject thiz)
{
    int fd = 0;
    int ret = 0;
    int i = 0, k = 0;
    int flag = 0;
    unsigned char cmdbuff[ ] = {0x1F, 0x06, 0x00, 0x24, 0x00, 0x00, 0xCA, 0x7F};
    unsigned char readbuff[128] = {0};
    int readok = 0;

    fd = openserial(DEV_PATH_ElecScale);
    if (fd < 0)
    {
//        LOGE("Open ElecScale serial(%s) error.", DEV_PATH_ElecScale);
        return -1;
    }

    ret = setSerial(fd, DEV_BARD_ElecScale, DEV_NEven_ElecScale, DEV_NBIT_ElecScale, DEV_NSTOP_ElecScale, 1);
    if (ret != 0)
    {
//        LOGE("Set ElecScale serial(%s) error.", DEV_PATH_ElecScale);
        close(fd);
        return  -2;
    }


    /*
    地址编号为1F模块清零：
    输入：1F 06 00 24 00 00 CA 7F
    回复：1F 06 00 24 00 00 CA 7F
    */
    for (int i = 0; i < 3; i++)
    {
        RS485Write();
        ret = write(fd, cmdbuff, sizeof(cmdbuff));
        if (ret != sizeof(cmdbuff))
        {
            continue;
        }
        RS485Read();
        ret = select_read(fd, readbuff, sizeof(readbuff), 1);
        if (ret <=  0)
        {
            continue;
        }

        flag = 0;
        for (k = 0; k <= ret - 7; k++)
        {
            //1F 03 02 4E 02 A4 27
            if (readbuff[k] == 0x1f  && readbuff[k+1] == 0x06
                && readbuff[k+2] == 0x00) {
                flag = 1;
                break;
            }
        }

        if (flag && (CRC16(readbuff + k, 7) == 0))
        {
           readok = 1;
           break;
        }
    }

    close(fd);

    if (readok)
        return 0;
    else
        return -3;
}

#define  DEV_PATH_CardReader  "/dev/ttySAC3"

extern "C"
JNIEXPORT jstring JNICALL
Java_com_ensentec_Lib_EnsenLib_CardGetID(
        JNIEnv *env,
        jobject /* this */)
{
    int fd = 0;
    int ret = 0;
    int flag = 0;
    int i = 0;

    unsigned char readbuff[128] = {0};
    char cCardNo[32] = {0};

    std::string hello;
    fd = openserial(DEV_PATH_CardReader);
    if (fd < 0)
    {
        LOGE("CardReader open serial(%s) error.", DEV_PATH_CardReader);
        hello = "-1";
        return env->NewStringUTF(hello.c_str());
    }

    ret = setSerial(fd, 9600, 'N', 8, 1, 1);
    if (ret != 0)
    {
        LOGE("CardReader set serial(%s) error.", DEV_PATH_ElecScale);
        close(fd);
        hello = "-2";
        return env->NewStringUTF(hello.c_str());
    }
    ret = select_read(fd, readbuff, sizeof(readbuff), 1);
    if (ret ==  0)
    {
        //LOGE("Read CardReader serial(%s) error.", DEV_PATH_ElecScale);
        close(fd);
        hello = "0";
        return env->NewStringUTF(hello.c_str());;
    }
    else if (ret < 0)
    {
        LOGE("CardReader Read serial(%s) error.", DEV_PATH_ElecScale);
        close(fd);
        hello = "0";
        return env->NewStringUTF(hello.c_str());;
    }
    else if (ret < 12)
    {
        hello = "-3";
        close(fd);
        return env->NewStringUTF(hello.c_str());;
    }
    else
    {
        flag = 0;
        for (i = 0; i <= ret -12; i++)
        {
            if (readbuff[i] == 0x55 && readbuff[i+1] == 0xaa)
            {
                flag = 1;
                break;
            }
        }

        //卡号格式为: 卡号后4位直接转成10进制数字串;
        int cardno = (readbuff[i+7] << 24) & 0xff000000 |
                (readbuff[i+8] << 16 ) & 0x00ff0000 |
                (readbuff[i+9] << 8  ) & 0x0000ff00 |
                (readbuff[i+10]      ) & 0x000000ff;

        snprintf(cCardNo, 31, "%d", cardno);
        close(fd);
        return env->NewStringUTF(cCardNo);
    }

}


#define  DEV_PATH_Printer  "/dev/ttySAC1"

extern "C"
JNIEXPORT int JNICALL
Java_com_ensentec_Lib_EnsenLib_Printerprint(
        JNIEnv *env,
        jobject /* this */,
        jbyteArray  byteArticle,
        jbyteArray  byteCode
    )
{
    int fd = 0;
    int ret = 0;

    unsigned char cmd1[3] = {0x1b, 0xb1, 0x01};
    unsigned char cmd2[ ] = {0x1B, 0x61, 0x01,      //居中显示
                             0x1D, 0x68, 0x38,      //条码高度38
                             0x1D, 0x77, 0x02,      //条码宽度02 (最小值)
                             0x1D, 0x48, 0x02, 0x1D, 0x6B, 0x49, 0x03 //打印条码指令, 采用CODE128格式, 0x03 是长度
                             };

    unsigned char cmd3[ ] = {0x0A};

    int len = env->GetArrayLength(byteArticle);
    jbyte * byteArr=env->GetByteArrayElements(byteArticle,0);
    char * buf = (char *)byteArr;

    int len2 = env->GetArrayLength(byteCode);
    jbyte * byteArr2=env->GetByteArrayElements(byteCode,0);
    char * buf2 = (char *)byteArr2;

    fd = openserial(DEV_PATH_Printer);
    if (fd < 0)
    {
        LOGE("Printer open serial(%s) error.", DEV_PATH_CardReader);
        return (-1);
    }

    ret = setSerial(fd, 115200, 'N', 8, 1, 1);
    if (ret != 0)
    {
        LOGE("Printer set serial(%s) error.", DEV_PATH_ElecScale);
        close(fd);
        return (-2);
    }

    /*
     * 居中显示
     * */
    ret = select_write(fd, cmd1, sizeof(cmd1), 1);
    if (ret <=  0)
    {
        //LOGE("Read CardReader serial(%s) error.", DEV_PATH_ElecScale);
        close(fd);
        return -3;
    }

    /*
     * 显示汉字
     * */
    ret = select_write(fd, (unsigned char *)buf, len, 1);
    if (ret <=  0)
    {
        //LOGE("Read CardReader serial(%s) error.", DEV_PATH_ElecScale);
        close(fd);
        return -3;
    }

//    ret = select_write(fd, (unsigned char *)cmd3, sizeof(cmd3), 1);
//    if (ret <=  0)
//    {
//        //LOGE("Read CardReader serial(%s) error.", DEV_PATH_ElecScale);
//        close(fd);
//        return -3;
//    }

    /*条码格式*/
    cmd2[sizeof(cmd2) - 1] = len2;
    ret = select_write(fd, cmd2, sizeof(cmd2), 1);
    if (ret <=  0)
    {
        //LOGE("Read CardReader serial(%s) error.", DEV_PATH_ElecScale);
        close(fd);
        return -3;
    }

    //打印条码
    ret = select_write(fd, (unsigned char *)buf2, len2, 1);
    if (ret <=  0)
    {
        //LOGE("Read CardReader serial(%s) error.", DEV_PATH_ElecScale);
        close(fd);
        return -3;
    }

    return 0;


}

